﻿/*///////////////////////////////////////////////////////////
Todo.as
Ben Smith
2009
///////////////////////////////////////////////////////////*/
package com.bsmith.app.presentation 
{
	import com.bsmith.app.model.TodoAppState;
	import com.flashdynamix.motion.TweensyZero;
	import flash.desktop.NativeApplication;
	import flash.desktop.SystemTrayIcon;
	import flash.display.Bitmap;
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.display.NativeMenu;
	import flash.display.NativeMenuItem;
	import flash.display.NativeWindowDisplayState;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.events.NativeWindowDisplayStateEvent;
	import flash.events.TextEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	
	/*===========================================================
	Todo
	Application Class
	===========================================================*/
	public class Todo extends MovieClip
	{
		static public const APP_NAME:String = "Jott";
		static public const APP_VER:String = "1.0";
		static private const CHROME_HEIGHT:int = 10;
		
		static public const EVENT_FORCE_MINIMIZE:String = "td.efmn";
		
		public var _smcHeaderBar:TodoHeaderBar;		//Body of app
		public var _smcTodoRoll:TodoRoll;			//Todo roll
		
		private var _configLoader:URLLoader = null;	//Config loader
		private var _iconLoader:Loader = null;		//Icon loader
		private var _xmlConfig:XML = null;			//XML config
		private var _bmpIcon:Bitmap = null;			//Icon
		
		/*-----------------------------------------------------------
		Todo - ctor
		-----------------------------------------------------------*/
		public function Todo() 
		{
			_configLoader = new URLLoader;
			_configLoader.addEventListener(Event.COMPLETE, onConfigLoaded, false, 0, true);
			_configLoader.addEventListener(IOErrorEvent.IO_ERROR, onConfigLoadingError, false, 0, true);
			_configLoader.load(new URLRequest("config.xml"));
			
			this.stage.scaleMode = StageScaleMode.NO_SCALE;
			this.stage.align = StageAlign.TOP_LEFT;
			this.doubleClickEnabled = true;	
			
			//Create active todo roll
			_smcTodoRoll = new ActiveTodoRoll;
			this.addChildAt(_smcTodoRoll, 0);
			
			this.alpha = 0;
		}
		
		/*-----------------------------------------------------------
		onConfigLoadingError
		Triggers when the config file could not be loaded
		-----------------------------------------------------------*/
		private function onConfigLoadingError(e:IOErrorEvent):void 
		{
			releaseConfigLoader();
		}
		/*-----------------------------------------------------------
		onConfigLoaded
		Triggers when config file was successfully loaded
		-----------------------------------------------------------*/
		private function onConfigLoaded(e:Event):void 
		{
			releaseConfigLoader();
			_xmlConfig = XML(_configLoader.data);
			_iconLoader = new Loader;
			_iconLoader.contentLoaderInfo.addEventListener(Event.INIT, onIconLoaded);
			_iconLoader.load(new URLRequest("icon.png"));
		}
		/*-----------------------------------------------------------
		releaseConfigLoader
		Releases config loader
		-----------------------------------------------------------*/
		private function releaseConfigLoader():void
		{
			_configLoader.removeEventListener(Event.COMPLETE, onConfigLoaded);
			_configLoader.removeEventListener(IOErrorEvent.IO_ERROR, onConfigLoadingError);
		}
		/*-----------------------------------------------------------
		onIconLoaded
		Saves the loaded icon
		-----------------------------------------------------------*/
		private function onIconLoaded(e:Event):void 
		{
			_iconLoader.contentLoaderInfo.removeEventListener(Event.INIT, onIconLoaded);
			_bmpIcon = Bitmap(_iconLoader.contentLoaderInfo.content);
			_iconLoader = null;
			
			//Set sys tray icon
			if (NativeApplication.supportsSystemTrayIcon)
			{
				var icon:SystemTrayIcon = SystemTrayIcon(NativeApplication.nativeApplication.icon);
				icon.tooltip = APP_NAME;
				icon.bitmaps = [_bmpIcon];
				icon.menu = createSysTrayMenu();
				icon.addEventListener(MouseEvent.CLICK, onClickSysTrayIcon, false, 0, true);
				this.stage.nativeWindow.addEventListener(NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING, onDisplayStateChanging);
			}
			
			initialize();
		}
		
		/*-----------------------------------------------------------
		createSysTrayMenu
		Creates a new system tray menu
		-----------------------------------------------------------*/
		private function createSysTrayMenu():NativeMenu
		{
			var menu:NativeMenu = new NativeMenu;
			var itemExit:NativeMenuItem = new NativeMenuItem("Exit");
			itemExit.addEventListener(Event.SELECT, closeApp, false, 0, true);
			menu.addItem(new NativeMenuItem(APP_NAME+" v" + APP_VER));
			menu.addItem(new NativeMenuItem("", true));
			menu.addItem(itemExit);
			return menu;
		}
		
		/*-----------------------------------------------------------
		closeApp
		Closes application
		-----------------------------------------------------------*/
		private function closeApp(e:Event):void 
		{
			this.stage.nativeWindow.close();
		}
		
		/*-----------------------------------------------------------
		onDisplayStateChanging
		User is changing the display state of the window
		-----------------------------------------------------------*/
		private function onDisplayStateChanging(e:NativeWindowDisplayStateEvent):void 
		{
			if (e.afterDisplayState == NativeWindowDisplayState.MINIMIZED)
			{
				e.preventDefault();
				dock();
			}
		}
		
		/*-----------------------------------------------------------
		onClickSysTrayIcon
		User clicks the system tray icon
		-----------------------------------------------------------*/
		private function onClickSysTrayIcon(e:MouseEvent):void 
		{
			undock();
		}
		
		/*-----------------------------------------------------------
		dock
		Docks application
		-----------------------------------------------------------*/
		private function dock(e:Event=null):void
		{
			stage.nativeWindow.visible = false;
		}

		/*-----------------------------------------------------------
		undock
		Undocks application
		-----------------------------------------------------------*/
		private function undock(e:Event=null):void
		{
			stage.nativeWindow.visible = true;
			stage.nativeWindow.orderToFront();
		}
		
		/*-----------------------------------------------------------
		initialize
		Initializes app once config loaded
		-----------------------------------------------------------*/
		private function initialize():void
		{
			_smcHeaderBar.addEventListener(EVENT_FORCE_MINIMIZE, dock);
			_smcHeaderBar.initialize();
			_smcTodoRoll.addEventListener(TodoRoll.EVENT_VIEW_UPDATED, updateView, false, 0, true);
			_smcTodoRoll.initialize();
			TodoAppState.instance.initialize();
			
			TweensyZero.to(this, {alpha:1}, 2);
		}
		
		/*-----------------------------------------------------------
		updateView
		Updates application view
		-----------------------------------------------------------*/
		private function updateView(e:Event):void 
		{
			this.stage.nativeWindow.height = this.height + CHROME_HEIGHT;
		}
	}
}